*Replication code to create plots in "Cruelty Campaign: Solitary Confinement in US Immigration Detention, 09/17/2025"

******************************FIGURE 1******************************
*Figure 1: Percentage Change in Reported Number of People Placed in Solitary Confinement within Immigration Detention
*data prep
use monthly_solitary.dta, clear
collapse (sum) Placement (lastnm) Month, by(modate)
tsset modate
gen change_placements=round(100*(d.Placements/l.Placements))
gen percent=strofreal(change_p) + "%"
drop if modate==tm(2024m4) | modate==tm(2024m12) | modate==tm(2025m1) | modate==tm(2025m2) // exclude months
sort modate
gen id=_n
label define idl 1 "May" 2 "June" 3 "July" 4 "August" 5 "September" 6 "October" 7 "November" 8 "March" 9 "April" 10 "May" 
label values id idl

*plot
twoway (bar change id if id==1 | id==2 | id==4 | id==5 | id==8 | id==9, barwidth(0.8) fcolor(red) lcolor(none) ylabel(-10(10)20) mla(percent) mlabpos(6) mlabsize(small) mlabcolor(black)) ///
(bar change id if id==3 | id==6 | id==7 | id==10, barwidth(0.8) fcolor(edkblue) lcolor(none) ylabel(-10(5)20) mla(percent) mlabpos(12) mlabsize(small) mlabcolor(black)), ///
scheme(s1color) xlabel(#10, labsize(small)) legend(off) yline(0, lcolor(gs8)) plotregion(margin(zero)) yscale(off)  xtitle(, size(medlarge) color(navy) margin(medium))  xline(7.5, lpattern(dash)) plotregion(lwidth(none)) xlabel(1 "May" 2 "June" 3 "July" 4 "August" 5 "September" 6 "October" 7 "November" 8 "March" 9 "April" 10 "May") xtitle("                         2024                                                  2025") 


******************************FIGURE 2******************************
*Figure 2: Number of Individuals in Solitary Confinement per 10,000 Book-ins, April 2024 – May 2025
use bookins_2024_2025.dta, clear
twoway (connected Prop modate, sort lcolor(orangebrown) mcolor(orangebrown)), xlabel(772 774 776 778 780 782 784) scheme(s1color) ylabel(0(100)500) xtitle("") ytitle("Proportion in Solitary") plotregion(lwidth(none))


******************************FIGURE 3******************************
*Figure 3: Top 15 Facilities by Number of Individuals Held in Solitary Confinement, April 2024 – May 2025
*data prep
use adp_placements.dta,  clear
sort facilities
keep if placement_r>66
gen short=[_n]
label define shortl 1 "Buffalo" 2 "Caroline" 3 "Central Louisiana" 4 "Denver" 5 "El Paso" 6 "Eloy" 7 "Florence" 8 "Imperial" 9 "Krome" 10 "Montgomery" 11 "Moshannon" 12 "Nevada" 13 "Prairieland" 14 "Farmville"  15 "South Texas"
label values short shortl
label var placements "Number of People in Solitary"
gen size=1 if capacity<600 // create relative size for the bubbles
replace size=2 if capacity>=600 & capacity<800
replace size=3 if capacity>=800 & capacity<1000
replace size=4 if capacity>=1000 & capacity<1200
replace size=5 if capacity>=1200 & capacity<1400
replace size=6 if capacity>=1400
generate pos = 3 // declutter facility names on the plot
replace pos=1 if short==3 | short==7
replace pos=4 if short==12 | short==2 | short==5 | short==8

*plot
twoway 	(scatter placements short if size==1, mcolor(black) msize(small) ///
			mlabel(short) mlabcolor(black) mlabsize(small) mlabvposition(pos)) ///
		(scatter placements short if size==2, mcolor(black) msize(medsmall) ///
			mlabel(short) mlabcolor(black) mlabsize(small) mlabvposition(pos))  ///
		(scatter placements short if size==3, mcolor(black) msize(medium) ///
			mlabel(short) mlabcolor(black) mlabsize(small) mlabvposition(pos)) /// 
		(scatter placements short if size==4, mcolor(black) msize(medlarge) ///
			mlabel(short) mlabcolor(black) mlabsize(small) mlabvposition(pos))  ///
		(scatter placements short if size==5, mcolor(black) msize(large) ///
			mlabel(short) mlabcolor(black) mlabsize(small) mlabvposition(pos))  ///
		(scatter placements short if size==6, mcolor(black) msize(vlarge) ///
			mlabel(short) mlabcolor(black) mlabsize(small) mlabvposition(pos)),  ///
		xscale(off) xscale(range(0 18)) xlabel(none, labels angle(stdarrow) valuelabel) ///
		legend( order(1 "Size of bubble indicates relative size of each facility") cols(1) position(6) size(medsmall)) ///
		graphregion(fcolor(white) ifcolor(white)) plotregion(fcolor(white) ifcolor(white))

******************************FIGURE 4******************************
*Figure 4: Vulnerable Populations in Solitary Confinement, Quarter 1, 2022 – Quarter 2, 2025 
use "vulnerable_populations.dta", clear
twoway (line NumberofPlacements qdate if PlacementR=="Total Unique", lcolor(orangebrown)) (line NumberofPlacements qdate if PlacementR=="Grand Total", lcolor(edkblue)), ylabel(0(100)650) xlabel(#14, valuelabel) legend(order(1  "Unique individuals" 2 "Total placements") rows(2) ring(0) position(4)) scheme(s1color) xline(251.5 255.5 259.5, lcolor(gs14)) ttext(650 249.5 "FY2022" 650 253.5 "FY2023" 650 257.5 "FY2024" 650 260.5 "FY2025", size(medlarge) ) ytitle("Frequency", size(medlarge) margin(medsmall)) plotregion(lcolor(none)) xtitle("")


******************************FIGURE 5******************************
*Figure 5: Average Length of Solitary Confinement for People with Vulnerabilities, Quarter 1, 2022 – Quarter 2, 2025
use "vulnerable_populations.dta", clear
keep if PlacementR=="Grand Total"
twoway (line AverageNumberofConsecutiveDa qdate, lcolor(orangebrown)) (line AverageNumberofCumulativeDay qdate, lcolor(edkblue)), ylabel(0(10)70) xlabel(#14, valuelabel) legend(order(1  "Consecutive Days by Quarter" 2 "Cumulative Days by Quarter") rows(2) ring(0) position(4)) scheme(s1color) xline(251.5 255.5 259.5, lcolor(gs14)) ttext(70 249.5 "FY2022" 70 253.5 "FY2023" 70 257.5 "FY2024" 70 260.5 "FY2025", size(medlarge) ) ytitle(Average Number of Days, size(medlarge) margin(medsmall)) plotregion(lcolor(none)) xtitle("")


******************************FIGURE 7******************************
*Mean and Median Lengths of Solitary Confinement in New England vs. Nationally, September 2018 – September 2023
*prep data
use srms_data.dta, clear
sum Length, det 
sum Length if NE==1, det
set obs 14258
replace Facility="Nationally" in 14258
set obs 14259
replace Facility="New England" in 14259
gen figure7=Facility=="Nationally" | Facility=="New England"
drop if figure7!=1
egen meanLength=mean(Length), by(Facility)
egen medianLength=median(Length), by(Facility)
label var meanLength "Mean Length"
label var medianLength "Median Length"
replace meanLength=26.49 if Facility=="Nationally"
replace medianLength=15 if Facility=="Nationally"
replace meanLength=28.61 if Facility=="New England"
replace medianLength=22 if Facility=="New England"
gen neworder=1 if Facility=="New England"
replace neworder=2 if Facility=="Nationally"
label define neworderl 1 "New England" 2 "Nationally", modify
label values neworder neworderl

*plot
graph bar (mean) meanLength medianLength, over(neworder, label(labsize(small)) relabel(`r(relabel)')) legend(label(1 "Mean Length") label(2 "Median Length") on cols(2) position(1)) bar(1, fcolor(edkblue) lcolor(none)) bar(2, fcolor(orangebrown) lcolor(none)) ytitle("Number of Days") bargap(10) blabel(bar, format(%4.0f)) graphregion(margin(large)) ylabel(0(5)30)


******************************FIGURE 8******************************
*Figure 8: Number of Unique Individuals Placed in Solitary Confinement in New England Facilities, April 2024 – May 2025
use monthly_solitary.dta, clear 
collapse (sum) Placement, by(modate NE)
label var Placement Placements 
twoway (bar Placement modate if NE==1, lcolor(orangebrown) bcolor(orangebrown) barwidth(0.8)), xlabel(#9) scheme(s1color) ytitle(Number of Individuals in Solitary) xline(778.5, lcolor(edkblue) lpattern(dash))


******************************FIGURE 9******************************
*Figure 9: Length of Solitary Confinement Placements in New England Facilities Involving People with a Reported Mental Illness, September 2018 – September 2023
*prepare data
use srms_data.dta, clear
keep if Mental_b==1
sum Length, det // 25
sum Length if NE==1, det // 19
set obs 3523
replace Facility="Nationally" in 3523
set obs 3524
replace Facility="New England" in 3524
gen figure=NE==1 | Facility=="Nationally" | Facility=="New England"
drop if figure!=1

egen meanLength=mean(Length), by(Facility)
egen medianLength=median(Length), by(Facility)
label var meanLength "Mean Length"
label var medianLength "Median Length"
replace Facility="Bristol County Detention Center (MA)" if Facility=="BRISTOL COUNTY DETENTION CENTER (MA)"
replace Facility="Plymouth County Correctional Facility (MA)" if Facility=="PLYMOUTH COUNTY CORRECTIONAL FACILITY (MA)"
replace Facility="Strafford County Corrections (NH)" if Facility=="STRAFFORD COUNTY CORRECTIONS (NH)"
replace Facility="Wyatt Detention Center (RI)" if Facility=="WYATT DETENTION CENTER (RI)"
replace meanLength=24.78 if Facility=="Nationally"
replace medianLength=10 if Facility=="Nationally"
replace meanLength=18.78 if Facility=="New England"
replace medianLength=8 if Facility=="New England"
gen neworder=1 if Facility=="Bristol County Detention Center (MA)"
replace neworder=2 if Facility=="Plymouth County Correctional Facility (MA)"
replace neworder=3 if Facility=="Strafford County Corrections (NH)"
replace neworder=4 if Facility=="Wyatt Detention Center (RI)"
replace neworder=5 if Facility=="New England"
replace neworder=6 if Facility=="Nationally"
label define neworderl 1 "Bristol County Detention Center" 2 "Plymouth County Correctional Facility" 3 "Strafford County Corrections" 4 "Wyatt Detention Center" 5 "New England" 6 "Nationally", modify
label values neworder neworderl

*plot
splitvallabels neworder , length(12) recode
graph bar (mean) meanLength medianLength, over(neworder, label(labsize(small)) relabel(`r(relabel)')) legend(label(1 "Mean Length") label(2 "Median Length") on cols(2) position(1)) bar(1, fcolor(edkblue) lcolor(none)) bar(2, fcolor(orangebrown) lcolor(none)) ytitle("Number of Days") bargap(10) blabel(bar, format(%4.0f)) graphregion(margin(large)) ylabel(0(10)70)

******************************FIGURE 10******************************
*Figure 10: Percentage of Solitary Confinement Placements in New England Facilities Involving People with a reported Mental Illness, September 2018 – September 2023
*prepare data
use srms_data.dta, clear
keep if NE==1
gen Mental_graph=1 if Mental_bin==1
gen NonMental_graph=1 if Mental_bin==0
label var Mental_graph "Mental Illness"
label var NonMental_graph "No Mental Illness"
*plot
graph bar (count) NonMental_g (count) Mental_g, over(ReleaseY)  percentages stack bar(1, fcolor(edkblue)) bar(2, fcolor(orangebrown))  ytitle(`"Percent"') legend(on order(1 "`: var label NonMental_g'" 2 "`: var label Mental_g'")) scheme(s1color) graphregion(fcolor(white)) note("Only showing placements were mental health status was reported.")